package com.youzan.cloud.biz.integral;
import com.youzan.cloud.biz.integral.common.CommandHandler;
import com.youzan.cloud.biz.integral.common.UserCase;
import com.youzan.cloud.biz.integral.common.UserCommand;
import com.youzan.cloud.biz.integral.usercase.DefaultPointUserCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/**
 * 积分业务组件实例
 * @author hlin
 */

@Service
@Lazy
public class PointIntegrationComponent {

    private static final Logger log = LoggerFactory.getLogger(PointIntegrationComponent.class);

    private boolean readyForWork = false;
    private Map<String, UserCase<?>> userCaseMap;

    @Resource
    private DefaultPointUserCase defaultPointUserCase;

    @PostConstruct
    public void init(){
        log.info("init point integration component, start load user cases...");
        loadUserCases();
        this.readyForWork = true;
    }


    private void loadUserCases() {
        userCaseMap = new HashMap<>(10);

        // register use case
        Map<String, Object> userCases = ContextUtils.getApplicationContext().getBeansWithAnnotation(CommandHandler.class);

        userCases.forEach((key, bean) -> {
            // 由于Spring 通过代理将Bean进行管理， 所以获取注解时需要从父类中获取
            userCaseMap.put(bean.getClass().getSuperclass().getAnnotation(CommandHandler.class).responseFor().getSimpleName(), (UserCase<?>) bean);
        });
    }

    public void execCommand(UserCommand cmd) throws Exception{
        if (!readyForWork) {
            return;
        }
        if(cmd.isAsync()) {
            dotAsyncCommand(cmd);
        } else {
            doExecCommand(cmd);
        }
    }

    private void dotAsyncCommand(UserCommand cmd) {
        // TODO implement this
        throw new NotImplementedException();
    }

    private void doExecCommand(UserCommand cmd) throws Exception {
            userCaseMap.getOrDefault(cmd.getClass().getSimpleName(), defaultPointUserCase).exec(cmd);
    }
}
